package controller

import (
	"encoding/json"
	"errors"
	"fmt"
	"strings"

	"v8s-ssp-proxy/internal/types"
)

const (
	resourceIDValuesCount = 7
	resourceIDIndex       = 6
)

func resourceCode(resourceID string) (string, error) {
	if parts := strings.Split(resourceID, ":"); len(parts) >= resourceIDValuesCount {
		return parts[resourceIDIndex], nil
	}

	return "", errors.New("failed to get resourceCode: invalid resourceID value")
}

func functionStatus(stageCode, stageStatus string) string {
	if stageStatus == "ERROR" {
		return "ERROR"
	}

	if stageCode == "INIT" {
		return "IN_PROGRESS"
	}

	if stageCode == "CREATE_TENANT" {
		if stageStatus == "COMPLETE" {
			return "COMPLETE"
		}

		return "IN_PROGRESS"
	}

	if stageCode == "REMOVE_SERVICE" {
		if stageStatus == "COMPLETE" {
			return "COMPLETE"
		}

		return "IN_PROGRESS"
	}

	if stageCode == "STOPPING" {
		if stageStatus == "COMPLETE" {
			return "COMPLETE"
		}

		return "IN_PROGRESS"
	}

	if stageCode == "RESUME" {
		if stageStatus == "COMPLETE" {
			return "COMPLETE"
		}

		return "IN_PROGRESS"
	}

	// TODO
	return "IN_PROGRESS"
}

func resourceStatus(functionStatus, stageCode, stageStatus string) string {

	if functionStatus == "ERROR" {
		return "ERROR"
	}

	if functionStatus == "COMPLETE" {
		if stageCode == "REMOVE_SERVICE" {
			return "DELETED"
		}

		if stageCode == "CREATE_TENANT" {
			return "READY"
		}

		if stageCode == "STOPPING" {
			return "PAUSED"
		}

		if stageCode == "RESUME" {
			return "READY"
		}

		return "READY"
	}

	if functionStatus == "IN_PROGRESS" {
		if stageCode == "REMOVE_SERVICE" {
			return "TERMINATING"
		}

		if stageCode == "CREATE_TENANT" {
			return "PROVISIONING"
		}

		if stageCode == "STOPPING" {
			return "STOPPING"
		}

		if stageCode == "RESUME" {
			return "RESUMING"
		}
	}

	// TODO
	return ""
}

func initContent(resourceId string, content map[string]string, projectCode string) (c string, err error) {

	if content == nil {
		content = make(map[string]string)
	}

	content["name"], err = resourceCode(resourceId)
	if err != nil {
		return
	}

	b, err := json.Marshal(content)
	if err != nil {
		return
	}

	return string(b), nil
}

func messageHeader(functionCode string) (string, string) {
	if functionCode != "" {
		return resourceStatusHeader, resourceFunctionHeader
	} else {
		return resourceStatusHeader, resourceStatusHeaderValue
	}
}

func endpointsMarkdown(task types.Task) string {
	if len(task.Endpoints) == 0 {
		return ""
	}

	builder := strings.Builder{}

	builder.WriteString("| **Service** | **Url** | **Description** |")
	builder.WriteString("\n")
	builder.WriteString("|-----------|-----------|-----------|")

	for _, endpoint := range task.Endpoints {
		builder.WriteString("\n")
		builder.WriteString(fmt.Sprintf("| %s | %s | %s |", endpoint.Type, endpoint.URL, endpoint.Description))
	}

	return builder.String()
}

func getConnectContent(content string) (string, string, error) {
	c := make(map[string]interface{}, 1)

	err := json.Unmarshal([]byte(content), &c)
	if err != nil {
		return "", "", fmt.Errorf("failed to unmarshal content json: %w", err)
	}

	composeJSON, ok := c["compose"].(string)
	if composeJSON == "" || !ok {
		return "", "", errors.New("failed to get compose JSON")
	}

	taskName, ok := c["sspResourceName"].(string)
	if taskName == "" || !ok {
		return "", "", errors.New("failed to get task name JSON")
	}

	return composeJSON, taskName, nil
}
